#include "NetworkBuffer.h"

NetworkBuffer* NetworkBuffer::_instance;
NetworkBuffer::Garbo NetworkBuffer::garbo;

NetworkBuffer::NetworkBuffer(void)
{
}

NetworkBuffer::~NetworkBuffer(void)
{
	CloseHandle(_fullSemaphore);
	CloseHandle(_emptySemaphore);
}

NetworkBuffer* NetworkBuffer::getInstance()
{
	if (!_instance)
	{
		_instance = new NetworkBuffer;
		_instance->init();
	}
	
	return _instance;
}




void NetworkBuffer::init()
{
	_inIndex = _outIndex = 0;

	_fullSemaphore  = CreateSemaphore(NULL, 0, BUFFER_LENGTH, NULL);
	_emptySemaphore = CreateSemaphore(NULL, BUFFER_LENGTH, 0, NULL);
}

bool NetworkBuffer::putData( Byte type, USHORT time, Byte right, Byte ahead )
{
	DWORD res = WaitForSingleObject(_emptySemaphore, 5);
	if (res == WAIT_TIMEOUT)
	{
		return false;
	}

	NetworkData* inPointer = &_buffer[_inIndex];
	inPointer->type = type;
	inPointer->time = time;
	if (type == HAMMER_MOVE)
	{
		inPointer->right = right;
		inPointer->ahead = ahead;
	}
	else
	{
		inPointer->right = 0;
		inPointer->ahead = 0;
	}

	_inIndex++;
	if (_inIndex == BUFFER_LENGTH)
	{
		_inIndex = 0;
	}

	ReleaseSemaphore(_fullSemaphore, 1, NULL);

	return true;
}

bool NetworkBuffer::getData(NetworkData* data)
{
	DWORD res = WaitForSingleObject(_fullSemaphore, 5);
	if (res == WAIT_TIMEOUT)
	{
		return false;
	}

	NetworkData* outPointer = &_buffer[_outIndex];
	data->type = outPointer->type;
	data->time = outPointer->time;
	data->right = outPointer->right;
	data->ahead = outPointer->ahead;

	_outIndex++;
	if (_outIndex == BUFFER_LENGTH)
	{
		_outIndex = 0;
	}

	return true;
}